package com.wxy.favorites.util;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Maps;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import com.wxy.favorites.core.BizException;

import java.awt.*;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class CaptchaUtils {

    private static final int CAPTCHA_WIDTH = 130;// 宽度
    private static final int CAPTCHA_HEIGHT = 48;// 高度
    private static final int CAPTCHA_LENGTH = 4;// 长度
    private static final int CHAR_TYPE_COUNT = 6;// 字符类型个数
    private static final int FONT_TYPE_COUNT = 10;// 字体个数
    private static final int ARITHMETIC_LENGTH = 3; // 算数长度

    private static final Cache<String, Object> timedCache = CacheBuilder.newBuilder().maximumSize(1000) // 设置缓存的最大容量
            .expireAfterWrite(1, TimeUnit.MINUTES) // 设置缓存在写入一分钟后失效
            .concurrencyLevel(10) // 设置并发级别为10
            .recordStats() // 开启缓存统计
            .build();

    public static Map<String, String> generate() {
        SpecCaptcha specCaptcha = new SpecCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LENGTH);
        String verCode = specCaptcha.text().toLowerCase();
        String key = UUID.fastUUID().toString();
        timedCache.put(key, verCode);
        Map<String, String> map = Maps.newHashMap();
        map.put("key", key);
        map.put("image", specCaptcha.toBase64());
        return map;
    }

    public static Map<String, String> generateRandom() {
        try {
            Captcha captcha = getRandomCaptcha();
            String verCode = captcha.text().toLowerCase();
            String key = UUID.fastUUID().toString();
            timedCache.put(key, verCode);
            Map<String, String> map = Maps.newHashMap();
            map.put("key", key);
            map.put("image", captcha.toBase64());
            return map;
        } catch (Exception e) {
            throw new BizException("获取验证码失败");
        }
    }

    private static Captcha getRandomCaptcha() throws IOException, FontFormatException {
        if(RandomUtil.randomBoolean()){
            SpecCaptcha specCaptcha = new SpecCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LENGTH);
            specCaptcha.setCharType(RandomUtil.randomInt(1, CHAR_TYPE_COUNT + 1));
            specCaptcha.setFont(RandomUtil.randomInt(0, FONT_TYPE_COUNT));
            return specCaptcha;
        }else{
            SimpleArithmeticCaptcha simpleArithmeticCaptcha = new SimpleArithmeticCaptcha();
            simpleArithmeticCaptcha.setWidth(CAPTCHA_WIDTH);
            simpleArithmeticCaptcha.setHeight(CAPTCHA_HEIGHT);
            simpleArithmeticCaptcha.setLen(RandomUtil.randomInt(2, ARITHMETIC_LENGTH + 1));
            return simpleArithmeticCaptcha;
        }
    }

    public static boolean verify(String key, String code) {
        Object verCode = timedCache.getIfPresent(key);
        if (verCode != null && code.equalsIgnoreCase(verCode.toString())) {
            timedCache.invalidate(key);
            return true;
        }
        return false;
    }
}
